﻿// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;

namespace Microsoft.AspNetCore.Http
{
    public class StreamPipeWriterBenchmark
    {
        private Stream _memoryStream;
        private StreamPipeWriter _pipeWriter;
        private static byte[] _helloWorldBytes = Encoding.ASCII.GetBytes("Hello World");
        private static byte[] _largeWrite = Encoding.ASCII.GetBytes(new string('a', 50000));

        [IterationSetup]
        public void Setup()
        {
            _memoryStream = new NoopStream();
            _pipeWriter = new StreamPipeWriter(_memoryStream);
        }

        [Benchmark]
        public async Task WriteHelloWorld()
        {
            await _pipeWriter.WriteAsync(_helloWorldBytes);
        }

        [Benchmark]
        public async Task WriteHelloWorldLargeWrite()
        {
            await _pipeWriter.WriteAsync(_largeWrite);
        }

        public class NoopStream : Stream
        {
            public override bool CanRead => false;

            public override bool CanSeek => throw new System.NotImplementedException();

            public override bool CanWrite => true;

            public override long Length => throw new System.NotImplementedException();

            public override long Position { get => throw new System.NotImplementedException(); set => throw new System.NotImplementedException(); }

            public override void Flush()
            {
            }

            public override int Read(byte[] buffer, int offset, int count)
            {
                throw new System.NotImplementedException();
            }

            public override long Seek(long offset, SeekOrigin origin)
            {
                throw new System.NotImplementedException();
            }

            public override void SetLength(long value)
            {
            }

            public override void Write(byte[] buffer, int offset, int count)
            {
            }

            public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
            {
                return Task.CompletedTask;
            }

            public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default(CancellationToken))
            {
                return default(ValueTask);
            }

            public override Task FlushAsync(CancellationToken cancellationToken)
            {
                return Task.CompletedTask;
            }
        }
    }
}
